package edu.umassd.raddacl.calc;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import edu.umassd.raddacl.DataSet;
import edu.umassd.raddacl.Observation;
import edu.umassd.raddacl.dist.DistanceCalculator;

/**
 * A table that contains calculated distances between observations.
 * 
 * @author Dan Avila
 * 
 */
@Component
public class DistanceTable implements LoopAndCompareAlgorithm
{
	private Map<Observation, Map<Observation, Double>> distanceTable = new HashMap<>();

	@Autowired
	private DistanceCalculator<Observation> calculator;

	@Autowired
	private DataSet dataSet;

	private int size;

	@PostConstruct
	protected void initialize()
	{
		dataSet.loop(this);
	}

	/**
	 * Measures the distance between two observations and stores that value in a
	 * table.
	 */
	@Override
	public void loop(Observation obs1, Observation obs2)
	{
		double d = calculator.distanceFrom(obs1, obs2);

		Map<Observation, Double> row = distanceTable.get(obs1);

		if (row == null)
		{
			row = new HashMap<>();
			distanceTable.put(obs1, row);
		}

		row.put(obs2, Double.valueOf(d));
		size++;
	}

	/**
	 * Gets the distance between two observations.
	 * 
	 * @param obs1
	 *            - the first observation.
	 * @param obs2
	 *            - the second observation.
	 * @return the distance between the two observations, or null if these
	 *         observations are not part of the dataset.
	 */
	public Double getDistance(Observation obs1, Observation obs2)
	{
		try
		{
			return distanceTable.get(obs1).get(obs2);
		}
		catch (NullPointerException e)
		{
			return null;
		}
	}

	/**
	 * Gets the number of comparisons contained within this table.
	 * 
	 * @return the number of entries in this table.
	 */
	public int size()
	{
		return size;
	}
}
